[IA64] Add head files and helper functions for VTD/ia64
authorIsaku Yamahata <yamahata@valinux.co.jp>
Wed, 22 Oct 2008 08:20:15 +0000 (17:20 +0900)
committerIsaku Yamahata <yamahata@valinux.co.jp>
Wed, 22 Oct 2008 08:20:15 +0000 (17:20 +0900)
Add head files and helper functions for VTD/ia64.

Signed-off-by: Anthony Xu <anthony.xu@intel.com>
xen/arch/ia64/vmx/viosapic.c
xen/arch/ia64/vmx/vmx_interrupt.c
xen/arch/ia64/xen/domain.c
xen/arch/ia64/xen/mm.c
xen/arch/ia64/xen/xensetup.c
xen/include/asm-ia64/domain.h
xen/include/asm-ia64/hvm/iommu.h [new file with mode: 0644]
xen/include/asm-ia64/hvm/irq.h [new file with mode: 0644]
xen/include/asm-ia64/linux-xen/asm/iosapic.h
xen/include/asm-ia64/linux/asm/hw_irq.h
xen/include/asm-ia64/vmx_platform.h

index 5a9ed27a716ed08afe795908af60c27bc71a3315..cf3bf9955dc58f2c9299992e55e72012bfeabb0b 100644 (file)
@@ -315,10 +315,6 @@ out:
     spin_unlock(&viosapic->lock);
 }
 
-#define hvm_pci_intx_gsi(dev, intx)  \
-    (((((dev) << 2) + ((dev) >> 3) + (intx)) & 31) + 16)
-        
-
 void viosapic_set_pci_irq(struct domain *d, int device, int intx, int level)
 {
     int irq;
index 50e19f0872957152d6d4211a1722ed0dcdff1a7e..c7939f7ced67532c3ccddf3b04aab140861b9595 100644 (file)
@@ -112,3 +112,45 @@ inject_guest_interruption(VCPU *vcpu, u64 vec)
     debugger_event(vec == IA64_EXTINT_VECTOR ?
                    XEN_IA64_DEBUG_ON_EXTINT : XEN_IA64_DEBUG_ON_EXCEPT);
 }
+
+void hvm_pci_intx_assert(
+        struct domain *d, unsigned int device, unsigned int intx)
+{
+    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    unsigned int gsi;
+
+    ASSERT((device <= 31) && (intx <= 3));
+
+    if ( __test_and_set_bit(device * 4 + intx, &hvm_irq->pci_intx.i) )
+        return;
+    gsi = hvm_pci_intx_gsi(device, intx);
+    if ( ++hvm_irq->gsi_assert_count[gsi] == 1 )
+        viosapic_set_irq(d, gsi, 1);
+}
+
+void hvm_pci_intx_deassert(
+        struct domain *d, unsigned int device, unsigned int intx)
+{
+    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    unsigned int gsi;
+
+    ASSERT((device <= 31) && (intx <= 3));
+
+    if ( !__test_and_clear_bit(device * 4 + intx, &hvm_irq->pci_intx.i) )
+        return;
+
+    gsi = hvm_pci_intx_gsi(device, intx);
+
+    if (--hvm_irq->gsi_assert_count[gsi] == 0)
+        viosapic_set_irq(d, gsi, 0);
+}
+
+void hvm_isa_irq_assert(struct domain *d, unsigned int isa_irq)
+{
+    /* dummy */
+}
+
+void hvm_isa_irq_deassert(struct domain *d, unsigned int isa_irq)
+{
+    /* dummy */
+}
index e1c07bfd6b9a0878021937332853d1b86fa8c465..679d0c3a9a0b902fba4c383818138c3b87678f09 100644 (file)
@@ -569,6 +569,7 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags)
        if (is_idle_domain(d))
            return 0;
 
+       INIT_LIST_HEAD(&d->arch.pdev_list);
        foreign_p2m_init(d);
 #ifdef CONFIG_XEN_IA64_PERVCPU_VHPT
        d->arch.has_pervcpu_vhpt = opt_pervcpu_vhpt;
index 7137f3e3d81f360cd6ad801504ddeb0b2fe3d7ab..f6a4b7eb1d200830b2fb00be2d6d1bf7a43a7c94 100644 (file)
@@ -3445,18 +3445,6 @@ void xencomm_mark_dirty(unsigned long addr, unsigned int len)
     __xencomm_mark_dirty(current->domain, addr, len);
 }
 
-int iommu_map_page(struct domain *d, unsigned long gfn, unsigned long mfn)
-{
-    /* STUB to compile */
-    return -ENOSYS;
-}
-
-int iommu_unmap_page(struct domain *d, unsigned long gfn)
-{
-    /* STUB to compile */
-    return -ENOSYS;
-}
-
 /*
  * Local variables:
  * mode: C
index fb242708d35266180f25932284a377706231dc05..923774a6e611f9e5e51cddfaab28ce1d296f1acb 100644 (file)
@@ -740,3 +740,15 @@ void arch_get_xen_caps(xen_capabilities_info_t *info)
     }
 }
 
+int xen_in_range(paddr_t start, paddr_t end)
+{
+    start = max_t(paddr_t, start, xen_pstart);
+    end = min_t(paddr_t, end, xen_pstart + XENHEAP_DEFAULT_SIZE);
+
+    return start < end;
+}
+
+int tboot_in_range(paddr_t start, paddr_t end)
+{
+    return 0;
+}
index db05a1119d6c79006487a6d587b2633f1aa77974..72857b9ab2185f667d5e9ba7bf2eead5b0d35017 100644 (file)
@@ -43,6 +43,8 @@ extern int shadow_mode_control(struct domain *d, xen_domctl_shadow_op_t *sc);
 extern void panic_domain(struct pt_regs *, const char *, ...)
      __attribute__ ((noreturn, format (printf, 2, 3)));
 
+#define has_arch_pdevs(d)    (!list_empty(&(d)->arch.pdev_list))
+
 struct mm_struct {
        volatile pgd_t * pgd;
     // atomic_t mm_users;                      /* How many users with user space? */
@@ -166,6 +168,7 @@ struct arch_domain {
     unsigned char rid_bits;            /* number of virtual rid bits (default: 18) */
     int breakimm;               /* The imm value for hypercalls.  */
 
+    struct list_head pdev_list;
     struct virtual_platform_def     vmx_platform;
 #define        hvm_domain vmx_platform /* platform defs are not vmx specific */
 
diff --git a/xen/include/asm-ia64/hvm/iommu.h b/xen/include/asm-ia64/hvm/iommu.h
new file mode 100644 (file)
index 0000000..f8f01d9
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef __ASM_IA64_HVM_IOMMU_H__
+#define __ASM_IA64_HVM_IOMMU_H__
+
+#include <asm/hvm/irq.h>
+#include <public/event_channel.h>
+#include <public/arch-ia64/hvm/save.h>
+#include <asm/linux-xen/asm/iosapic.h>
+
+struct iommu_ops;
+extern struct iommu_ops intel_iommu_ops;
+extern int intel_vtd_setup(void);
+
+#define iommu_get_ops() (&intel_iommu_ops)
+#define iommu_hardware_setup()  (intel_vtd_setup())
+
+static inline int domain_irq_to_vector(struct domain *d, int irq)
+{
+    return irq;
+}
+
+static inline void ack_APIC_irq(void)
+{
+    /* TODO */
+}
+
+static inline void pci_cleanup_msi(struct pci_dev *pdev)
+{
+    /* TODO */
+}
+
+#define AUTO_ASSIGN         -1
+
+extern int assign_irq_vector (int irq);
+
+#endif /* __ASM_IA64_HVM_IOMMU_H__ */
diff --git a/xen/include/asm-ia64/hvm/irq.h b/xen/include/asm-ia64/hvm/irq.h
new file mode 100644 (file)
index 0000000..d163e56
--- /dev/null
@@ -0,0 +1,106 @@
+/******************************************************************************
+ * irq.h
+ *
+ * Interrupt distribution and delivery logic.
+ *
+ * Copyright (c) 2006, K A Fraser, XenSource Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef __ASM_IA64_HVM_IRQ_H__
+#define __ASM_IA64_HVM_IRQ_H__
+
+#include <xen/irq.h>
+
+#define NR_VECTORS 256
+#define VIOAPIC_NUM_PINS  48
+#define NR_PIRQS   256
+
+#include <xen/hvm/irq.h>
+
+struct hvm_hw_pci_irqs {
+    /*
+     * Virtual interrupt wires for a single PCI bus.
+     * Indexed by: device*4 + INTx#.
+     */
+    union {
+        DECLARE_BITMAP(i, 32*4);
+        uint64_t pad[2];
+    };
+};
+
+struct hvm_irq {
+    /*
+     * Virtual interrupt wires for a single PCI bus.
+     * Indexed by: device*4 + INTx#.
+     */
+    struct hvm_hw_pci_irqs pci_intx;
+
+    /* Virtual interrupt and via-link for paravirtual platform driver. */
+    uint32_t callback_via_asserted;
+    union {
+        enum {
+            HVMIRQ_callback_none,
+            HVMIRQ_callback_gsi,
+            HVMIRQ_callback_pci_intx
+        } callback_via_type;
+    };
+    union {
+        uint32_t gsi;
+        struct { uint8_t dev, intx; } pci;
+    } callback_via;
+
+    /*
+     * Number of wires asserting each GSI.
+     *
+     * GSIs 0-15 are the ISA IRQs. ISA devices map directly into this space
+     * except ISA IRQ 0, which is connected to GSI 2.
+     * PCI links map into this space via the PCI-ISA bridge.
+     *
+     * GSIs 16+ are used only be PCI devices. The mapping from PCI device to
+     * GSI is as follows: ((device*4 + device/8 + INTx#) & 31) + 16
+     */
+    u8 gsi_assert_count[VIOAPIC_NUM_PINS];
+
+    /*
+     * GSIs map onto PIC/IO-APIC in the usual way:
+     *  0-7:  Master 8259 PIC, IO-APIC pins 0-7
+     *  8-15: Slave  8259 PIC, IO-APIC pins 8-15
+     *  16+ : IO-APIC pins 16+
+     */
+
+    /* Last VCPU that was delivered a LowestPrio interrupt. */
+    u8 round_robin_prev_vcpu;
+
+    struct hvm_irq_dpci *dpci;
+};
+
+#define hvm_pci_intx_gsi(dev, intx)  \
+    (((((dev)<<2) + ((dev)>>3) + (intx)) & 31) + 16)
+#define hvm_pci_intx_link(dev, intx) \
+    (((dev) + (intx)) & 3)
+
+/* Extract the IA-64 vector that corresponds to IRQ.  */
+static inline int
+irq_to_vector (int irq)
+{
+    return irq;
+}
+
+
+extern u8 irq_vector[NR_IRQ_VECTORS];
+extern int vector_irq[NR_VECTORS];
+
+#endif /* __ASM_IA64_HVM_IRQ_H__ */
index 1beb6162ba6e11eff71e71defbf8dce488ba80f5..d3d68ef08268002ae46507594f1790c16247b19b 100644 (file)
@@ -175,5 +175,8 @@ extern unsigned long ia64_vector_mask[];
 extern unsigned long ia64_xen_vector[];
 #endif /* XEN */
 
+#define IO_APIC_BASE(idx) ((unsigned int *)iosapic_lists[idx].addr)
+#define IO_APIC_ID(idx)   (iosapic_lists[idx].id)
+
 # endif /* !__ASSEMBLY__ */
 #endif /* __ASM_IA64_IOSAPIC_H */
index d27e8e7a77ac67fca5645f44fe1fc0224e37f9d3..9ecf9014056613669cb879819d1e1b2aa89e36b5 100644 (file)
@@ -124,13 +124,6 @@ irq_descp (int irq)
        return irq_desc + irq;
 }
 
-/* Extract the IA-64 vector that corresponds to IRQ.  */
-static inline ia64_vector
-irq_to_vector (int irq)
-{
-       return (ia64_vector) irq;
-}
-
 /*
  * Convert the local IA-64 vector to the corresponding irq number.  This translation is
  * done in the context of the interrupt domain that the currently executing CPU belongs
index deff5c29cfc45569faf02452cf52da7c8f8a6ad3..09f173aa4fb9569170cf60cca2f80bd47dc21c40 100644 (file)
 
 #include <public/xen.h>
 #include <public/hvm/params.h>
+#include <asm/hvm/irq.h>
 #include <asm/viosapic.h>
 #include <asm/hvm/vacpi.h>
+#include <xen/hvm/iommu.h>
 
 struct vmx_ioreq_page {
     spinlock_t          lock;
@@ -41,6 +43,9 @@ typedef struct virtual_platform_def {
     /* One IOSAPIC now... */
     struct viosapic             viosapic;
     struct vacpi                vacpi;
+    /* Pass-throgh VT-d */
+    struct hvm_irq              irq;
+    struct hvm_iommu            hvm_iommu;
 } vir_plat_t;
 
 static inline int __fls(uint32_t word)